#ifndef EAP_H
#define EAP_H

typedef unsigned char uchar;
typedef unsigned short ushort;

typedef enum  _TAG_EAPOL_TYPE{
  EAPOL_PACKET  	= 0x00,
  EAPOL_START   	= 0x01,
  EAPOL_LOGOFF  	= 0x02,
  EAPOL_KEEP_ALIVE	= 0xfc
}TAG_EAPOL_TYPE;

typedef enum _TAG_EAP_MSG_CODE{
  EAP_MSG_NOP		= 0x00,
  EAP_MSG_REQUEST   = 0x01,
  EAP_MSG_RESPONSE  = 0x02,
  EAP_MSG_SUCCESS   = 0x03,
  EAP_MSG_FAILURE   = 0x04
}TAG_EAP_MSG_CODE;

typedef enum _TAG_EAP_REQUEST_TYPE{
  EAP_REQ_IDENTITY      = 0x01,
  EAP_REQ_NOTIFICATION  = 0x02,
  EAP_NAK               = 0x03,
  EAP_REQ_MD5_CHALLENGE = 0x04,
  EAP_ONE_TIME_PASSWORD = 0x05,
  EAP_GEN_TOKEN_CART    = 0x06,
  EAP_REQ_HTTP_DIGEST   = 0x26,     //in haut university
  EAP_EXPAND_TPYE       = 0xfe
}TAG_EAP_REQUEST_TYPE;

typedef struct _PPP_FRAME{          //14Byte
  uchar   des_mac[6];
  uchar   sou_mac[6];
  ushort  frame_type;
  uchar   data[1];
}PPP_FRAME;

typedef struct  _EAPOL_FRAME{      //4Byte
  uchar   version;
  uchar   eapol_tpye;
  ushort  length;
  uchar   data[1];
}EAPOL_FRAME;

typedef struct  _EAP_MSG{       //4Byte
  uchar   code;
  uchar   identity;
  ushort  length;
  uchar   data[1];
}EAP_MSG;

typedef struct  _EAP_REQUEST{	//1Byte
  uchar   type;
  uchar   data[1];
}EAP_REQUEST;

typedef struct	_EAP_RESPONSE{	//1Byte
  uchar   type;
  uchar   data[1];
}EAP_RESPONSE;

/*API*/

//private


uchar* get_buffer(int size);
void release_buffer(uchar* buffer);

void init_ppp_frame(PPP_FRAME* ppp_frame);
void init_eapol(EAPOL_FRAME* eapol_frame, uchar eapol_type, ushort length);
void init_msg_frame(EAP_MSG* eap_msg, uchar code, uchar identity, ushort length);
int init_identity_responst(EAP_RESPONSE* response);
int init_md5_response(EAP_RESPONSE* response, uchar identity, uchar* attch_key, ushort attch_key_length);

//public
void global_init(uchar loc_mac[6], uchar loc_ip[4], char* dev, char* username, char* password);
void global_release();

void send_start();
void send_logoff();
void keep_alive();

void handle_ppp(uchar*  buffer);
void handle_eapol(EAPOL_FRAME* eaplol);
void handle_msg(EAP_MSG* msg);
void handle_request(EAP_REQUEST* request, uchar identity);
void handle_req_identity(EAP_REQUEST* request, uchar identity);
void handle_req_md5_challenge(EAP_REQUEST* request, uchar identity);
void handle_req_http_digest(EAP_REQUEST* request, uchar identity);
void handle_req_default(EAP_REQUEST* request);


//utils
void print_hex(uchar* buffer, ushort size);
#endif // EAP_H
